﻿using System;
using System.Data;
using System.Data.SqlClient;

namespace Models
{
    public abstract class DataAccessBase : IDisposable
    {
        #region Fields

        protected SqlCommand command;
        protected SqlConnection connection;
        protected SqlTransaction transaction;

        private readonly string _connectionString;

        //field brugt til at håndtere om klassen er disposed
        bool _disposed;

        #endregion

        #region Properties

        public SqlConnection Connection { get { return connection; } }
        public SqlCommand Command { get { return command; } }

        #endregion

        #region Creation

        protected DataAccessBase(DataAccessConnection state = DataAccessConnection.Closed)
        {
            _disposed = false;
            _connectionString = "Data Source=ealdb1.eal.local;Initial Catalog=EJL03_DB;Persist Security Info=True;User ID=ejl03_usr;Password=Baz1nga3;";

            InitializeConnection();

            if (state == DataAccessConnection.Open)
                OpenConnection();
        }

        #endregion

        #region Private Helpers

        private void InitializeConnection()
        {
            try
            {
                connection = new SqlConnection(_connectionString);
                command = connection.CreateCommand();
                command.CommandType = CommandType.StoredProcedure;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        #endregion

        #region Public Interface

        public void OpenConnection()
        {
            // når vi åbner en ny connection, skal vi ikke bruge de gamle connections
            command.Parameters.Clear();

            if (connection.State != ConnectionState.Open)
                connection.Open();
        }

        public void CloseConnection()
        {
            if (connection.State != ConnectionState.Closed)
                connection.Close();
        }

        public void BeginTransaction()
        {
            transaction = connection.BeginTransaction();
            command.Transaction = transaction;
        }

        public void CommitTransaction()
        {
            transaction.Commit();
        }

        public void RollBackTransaction()
        {
            transaction.Rollback();
        }

        protected SqlConnection NewConnection()
        {
            return new SqlConnection(_connectionString);
        }

        #endregion

        #region Destruct & Dispose

        ~DataAccessBase()
        {
            //false som argument definerer at den her metode ikke skal dispose, men den gør det alligevel hvis der er sket en fejl
            Dispose(false);
        }

        void IDisposable.Dispose()
        {
            // true some argument definerer at den her metode skal dispose
            Dispose(true);

            // fjern dette object fra finalization queue, da vi allerede har ryddet op med vores Dispose metode
            //GC.SuppressFinalize(this);
        }

        protected void Dispose(bool disposing)
        {
            // hvis Dispose ikke allerede er kaldt
            if (!_disposed)
            {
                // hvis connection ikke er lukket, luk den
                if (connection.State != ConnectionState.Closed)
                    connection.Close();

                // dispose connection og command object
                if (connection != null)
                    connection.Dispose();
                if (command != null)
                    command.Dispose();

                _disposed = true;
            }
        }

        #endregion
    }

    #region Enums

    public enum DataAccessConnection
    {
        Open,
        Closed
    }

    #endregion
}
